<!--
 * @Author: 郝奔 1425466221@qq.com
 * @Date: 2024-11-22 09:21:08
 * @LastEditors: 郝奔 1425466221@qq.com
 * @LastEditTime: 2024-12-26 13:51:33
 * @FilePath: /HG-dqbasic_open_platform/src/framework/components/dt-uploadAvatar/index.vue
 * @Description: 
 * Copyright (c) 2024-present HBIS Digital Technology Co.,Ltd. All rights reserved. 
-->
<script lang="ts" setup>
import Cropper from '../dt-cropper/index.vue'
import { cloud } from '@/framework/utils/request';
import { fileUpload } from '@/framework/api/upload-avatar/index'
import { useUserStoreHook } from '@/framework/store/modules/user';
import { selectFile, UploadFile, FileType, RawType } from '@/framework/api/upload-avatar/type'
import { ComponentInternalInstance } from 'vue'
const userStore = useUserStoreHook();
const fileUploadRef = ref()
const { proxy } = getCurrentInstance() as ComponentInternalInstance
const state = reactive({
  uploadData: { // 上传需要的额外参数
    siteId: 1,
    source: 1
  },
  action: import.meta.env.VITE_APP_BASE_API, // 上传地址，必填
  cropperImg: '', // 需要裁剪的图片
  showCropper: false, // 是否显示裁剪框
  uploadFile: {}, // 裁剪后的文件
  resultImg: '', // 上传成功，后台返回的路径,
  // 文件类型, 例如["doc", "xls", "ppt", "txt", "pdf"]
  fileType: ['png', 'jpg', 'jpeg']
})
defineExpose({
  state
})
// submit 之后会触发此方法
function httpRequest(request: { file: { name: string; type: string }; }): void {
  // 新建formDate对象 
  const formData = new FormData()
  // 假设 state.uploadFile 是一个 Blob 对象
  if (state.uploadFile instanceof Blob) {
    // 将 Blob 格式转为 File 格式（如果它不是已经是 File 类型的话）
    const files = new File([state.uploadFile], request.file.name, { type: request.file.type });
    formData.append('file', files);
    formData.append('secretFlag', 'N')

  }
  // // 将裁剪后的blob格式转为file格式
  // const files = new window.File(
  //   [state.uploadFile],
  //   request.file.name,
  //   { type: request.file.type }
  // )
  // formData.append('file', files)
  // formData.append('secretFlag', 'N')

  // loading.start() // 上传中的loading
  fileUpload(formData).then(({ data }) => {
    // state.resultImg = data.fileUrl
    state.resultImg = import.meta.env.VITE_APP_BASE_API + cloud.file + '/sysFileInfo/private/preview?fileId=' + data.fileId + '&token=' + userStore.token
    emits('success-upload', data)
    state.showCropper = false
  })
}
// 选择文件
function selectChange(file: selectFile, fileList: FileType[]): void {
  // 处理第二次选择图片时  filelist长度增加 多次触发httpRequest方法问题
  if (fileList.length > 1) {
    fileList.splice(0, 1)
  }
  const { raw } = file
  openCropper(raw)
}
/**
 * @param {file} 上传的文件
 */
function openCropper(file: RawType): boolean {
  const files = file
  const isLt5M = files.size > (5 << 20)
  if (isLt5M) {
    proxy?.$modal.msgError('请上传5M内的图片')
    return false
  }
  let fileExtension = ''
  if (file.name.lastIndexOf('.') > -1) {
    fileExtension = file.name.slice(file.name.lastIndexOf('.') + 1)
  }
  const isTypeOk = state.fileType.some((type) => {
    if (file.type.indexOf(type) > -1) return true
    if (fileExtension && fileExtension.indexOf(type) > -1) return true
    return false
  })
  if (!isTypeOk) {
    proxy?.$modal.msgError(`文件格式不正确, 请上传${state.fileType.join('/')}格式文件!`)
    return false
  }
  const reader = new FileReader()
  // eslint-disable-next-line @typescript-eslint/explicit-function-return-type
  reader.onload = e => {
    // let data
    // if (typeof e.target?.result === 'object') {
    //   // 把Array Buffer转化为blob 如果是base64不需要
    //   data = window.URL.createObjectURL(new Blob([e.target?.result]))
    // } else {
    //   data = e.target?.result
    // }
    let data: Blob | string | null; // 根据实际情况确定类型，这里假设它可能是Blob、字符串或null

    if (e.target?.result instanceof ArrayBuffer) {
      // 把Array Buffer转化为blob
      data = window.URL.createObjectURL(new Blob([e.target.result]));
    } else if (typeof e.target?.result === 'string') {
      // 假设这里也可能是字符串（比如base64编码的字符串）
      data = e.target.result;
    } else {
      // 如果result不是ArrayBuffer也不是字符串，则可能是null或其他类型
      // 根据你的需求处理这种情况，比如设置为null或抛出错误
      data = null;
    }

    data && (state.cropperImg = data)
    state.showCropper = true
  }
  // 转化为base64
  // reader.readAsDataURL(file)
  // 转化为blob
  reader.readAsArrayBuffer(files)
  return true
}
// 上传图片
function uploadImg(file: UploadFile): void {
  state.uploadFile = file
  fileUploadRef.value.submit()
}
// 更新图片
function updateCropper(): void {
  fileUploadRef.value.$children[0].$el.click()
}
// 关闭窗口
function closeDialog(): void {
  state.showCropper = false
}
const emits = defineEmits(['success-upload'])
function changeImg(img: string): void {
  state.resultImg = img
}
defineExpose({
  changeImg
})
</script>
<template>
  <div :class="$options.name">
    <el-upload ref="fileUploadRef" class="upload-el" accept="image/*" name="pic" :action="state.action"
      :data="state.uploadData" :on-change="selectChange" :show-file-list="false" :auto-upload="false"
      :http-request="httpRequest">
      <el-avatar v-if="state.resultImg" id="avatarImg" :size="100" :src="state.resultImg" icon="el-icon-user-solid" />
      <!-- <i v-else class="el-icon-plus avatar-uploader-icon" /> -->
      <plus v-else></plus>
    </el-upload>
    <Cropper v-if="state.showCropper" :dialog-visible="state.showCropper" :cropper-img="state.cropperImg"
      @update-cropper="updateCropper" @colse-dialog="closeDialog" @upload-img="uploadImg" />
  </div>
</template>


<style lang="scss" scoped>
.uploadAvatar {
  .video-image {
    display: flex;

    figure {
      width: 100px;

      img {
        width: 100%;
        display: block;
      }
    }
  }
}
</style>
